package com.iraeta.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iraeta.RequestItem;
import com.iraeta.common.MySession;
import com.iraeta.common.MySessionManager;
import com.iraeta.common.Result;
import com.iraeta.uitl.SpringContextUtil;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@RequestMapping(produces = {"application/json; charset=utf-8"})
public class BaseController{

    ThreadLocal<RequestItem> _requestItem = new ThreadLocal<>();

    protected RequestItem getRequestItem() {
        if (_requestItem.get() != null) {
            return _requestItem.get();
        }
        _requestItem.set((RequestItem) SpringContextUtil.getBean("requestItem"));
        return _requestItem.get();
    }

    @ModelAttribute
    public void setReqAndRes(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
        RequestItem requestItem = getRequestItem();
        requestItem.setRequest(request);
        requestItem.setResponse(response);
        String token = request.getHeader("X-Token");
        if (token == null) {
            token = "X-Token";
        }
        requestItem.setSession(MySessionManager.get(token));
    }

    protected HttpServletRequest getRequest() {
        return getRequestItem().getRequest();
    }
    protected HttpServletResponse getResponse() {
        return getRequestItem().getResponse();
    }
    protected MySession getSession() {
        return getRequestItem().getSession();
    }

    public int getUserId() {
        Object obj = getSession().getAttribute("currentUserId");
        if (obj == null)
            return 0;
        return (int) obj;
    }
    public String getUserName() {
        Object obj = getSession().getAttribute("currentUserName");
        if (obj == null)
            return "";
        return (String) obj;
    }
    public String getUserAvatar() {
        Object obj = getSession().getAttribute("currentUserAvatar");
        if (obj == null)
            return "";
        return (String) obj;
    }
    public List<Integer> getPermissions() {
        if (this.getSession().getAttribute("permissions") != null) {
            return (List<Integer>) (getSession().getAttribute("permissions"));
        }
        return new ArrayList<Integer>();
    }
    public void pageSet(JSONObject jsonObject){
        int pageNum = jsonObject.getIntValue("pageNum");
        int pageSize = jsonObject.getIntValue("pageSize");
        PageHelper.startPage(pageNum, pageSize);
    }
    public <T> PageInfo<T> getPageInfo(List<T> list){
        return new PageInfo<T>(list);
    }

    public String success(){
        return JSON.toJSONString(Result.success());
    }
    public String success(Object data){
        return JSON.toJSONString(Result.success(data));
    }

    /*前台的json数据转为实体类*/
    public void mapJsonToObj(JSONObject obj, Object item) {
        Method[] methods = item.getClass().getMethods();
        for (String k : obj.keySet()) {
            String lk = k.toLowerCase();
            Optional<Method> opMethod = Arrays.stream(methods).filter(s -> s.getName().toLowerCase().equals("set" + lk)).findFirst();
            if (!opMethod.isPresent())
                continue;

            Method method = opMethod.get();
            String fieldValue = obj.getString(k);
            if (fieldValue != null) {
                try {
                    Object targetValue;
                    String fieldType = method.getParameters()[0].getType().toString();
                    switch (fieldType) {
                        case "boolean":
                        case "class java.lang.Boolean":
                            if (fieldValue.equals("1") || fieldValue.equals("true")) {
                                targetValue = true;
                            } else {
                                targetValue = false;
                            }
                            break;
                        case "int":
                        case "class java.lang.Integer":
                            if (StrUtil.isEmpty(fieldValue)) {
                                targetValue = 0;
                            } else {
                                targetValue = Integer.parseInt(fieldValue);
                            }
                            break;
                        case "long":
                        case "class java.lang.Long":
                            if (StrUtil.isEmpty(fieldValue)) {
                                targetValue = 0;
                            } else {
                                targetValue = Long.parseLong(fieldValue);
                            }
                            break;
                        case "float":
                        case "class java.lang.Float":
                            if (StrUtil.isEmpty(fieldValue)) {
                                targetValue = 0;
                            } else {
                                targetValue = Float.parseFloat(fieldValue);
                            }
                            break;
                        case "double":
                        case "class java.lang.Double":
                            if (StrUtil.isEmpty(fieldValue)) {
                                targetValue = 0;
                            } else {
                                targetValue = Double.parseDouble(fieldValue);
                            }
                            break;
                        case "class java.math.BigDecimal":
                            if (StrUtil.isEmpty(fieldValue)) {
                                targetValue = 0;
                            } else {
                                targetValue = new BigDecimal(fieldValue);
                            }
                            break;
                        case "class java.util.Date":
                            if (StrUtil.isEmpty(fieldValue)) {
                                targetValue = null;
                            } else {
                                targetValue = DateUtil.parseDate(fieldValue);
                            }
                            break;
                        default:
                            if (StrUtil.isEmpty(fieldValue)) {
                                targetValue = null;
                            } else {
                                targetValue = fieldValue;
                            }
                            break;
                    }
                    method.invoke(item, targetValue);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
